#include <ctype.h>  /* NOLINT */
#include <stdio.h>  /* NOLINT */
#include <stdlib.h> /* NOLINT */
#include <string.h> /* NOLINT */

#if defined(_MSC_VER)
#pragma warning(disable : 4996) /* deprecation */
#endif

#include "E:/CODE/VTK/VTK-7.1.1/Testing/Rendering/vtkTestingObjectFactory.h"


/* Forward declare test functions. */
int TestAxisActor(int, char*[]);
int TestAxisActor2D(int, char*[]);
int TestAxisActor3D(int, char*[]);
int TestAxisActorText3D(int, char*[]);
int TestBarChartActor(int, char*[]);
int TestCaptionActor2D(int, char*[]);
int TestConvexHull2D(int, char*[]);
int TestCornerAnnotation(int, char*[]);
int TestCubeAxes2DMode(int, char*[]);
int TestCubeAxes3(int, char*[]);
int TestCubeAxesInnerGridAll(int, char*[]);
int TestCubeAxesInnerGridClosest(int, char*[]);
int TestCubeAxesInnerGridFurthest(int, char*[]);
int TestCubeAxesIntersectionPoint(int, char*[]);
int TestCubeAxesOrientedBoundingBox(int, char*[]);
int TestCubeAxesSticky(int, char*[]);
int TestCubeAxesStickyCentered(int, char*[]);
int TestCubeAxesWithGridLines(int, char*[]);
int TestCubeAxesWithXInnerGrids(int, char*[]);
int TestCubeAxesWithXInnerPolys(int, char*[]);
int TestCubeAxesWithXLines(int, char*[]);
int TestCubeAxesWithYInnerGrids(int, char*[]);
int TestCubeAxesWithYInnerPolys(int, char*[]);
int TestCubeAxesWithYLines(int, char*[]);
int TestCubeAxesWithZInnerGrids(int, char*[]);
int TestCubeAxesWithZInnerPolys(int, char*[]);
int TestCubeAxesWithZLines(int, char*[]);
int TestEmptyCornerAnnotation(int, char*[]);
int TestLegendBoxActor(int, char*[]);
int TestLegendBoxActor2(int, char*[]);
int TestLegendScaleActor(int, char*[]);
int TestPieChartActor(int, char*[]);
int TestPolarAxes(int, char*[]);
int TestScalarBar(int, char*[]);
int TestScalarBarAboveBelow(int, char*[]);
int TestSpiderPlotActor(int, char*[]);
int TestXYPlotActor(int, char*[]);


#ifdef __cplusplus
#define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR)
#else
#define CM_CAST(TYPE, EXPR) (TYPE)(EXPR)
#endif

/* Create map.  */

typedef int (*MainFuncPointer)(int, char* []);
typedef struct
{
  const char* name;
  MainFuncPointer func;
} functionMapEntry;

static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
    {
    "TestAxisActor",
    TestAxisActor
  },
  {
    "TestAxisActor2D",
    TestAxisActor2D
  },
  {
    "TestAxisActor3D",
    TestAxisActor3D
  },
  {
    "TestAxisActorText3D",
    TestAxisActorText3D
  },
  {
    "TestBarChartActor",
    TestBarChartActor
  },
  {
    "TestCaptionActor2D",
    TestCaptionActor2D
  },
  {
    "TestConvexHull2D",
    TestConvexHull2D
  },
  {
    "TestCornerAnnotation",
    TestCornerAnnotation
  },
  {
    "TestCubeAxes2DMode",
    TestCubeAxes2DMode
  },
  {
    "TestCubeAxes3",
    TestCubeAxes3
  },
  {
    "TestCubeAxesInnerGridAll",
    TestCubeAxesInnerGridAll
  },
  {
    "TestCubeAxesInnerGridClosest",
    TestCubeAxesInnerGridClosest
  },
  {
    "TestCubeAxesInnerGridFurthest",
    TestCubeAxesInnerGridFurthest
  },
  {
    "TestCubeAxesIntersectionPoint",
    TestCubeAxesIntersectionPoint
  },
  {
    "TestCubeAxesOrientedBoundingBox",
    TestCubeAxesOrientedBoundingBox
  },
  {
    "TestCubeAxesSticky",
    TestCubeAxesSticky
  },
  {
    "TestCubeAxesStickyCentered",
    TestCubeAxesStickyCentered
  },
  {
    "TestCubeAxesWithGridLines",
    TestCubeAxesWithGridLines
  },
  {
    "TestCubeAxesWithXInnerGrids",
    TestCubeAxesWithXInnerGrids
  },
  {
    "TestCubeAxesWithXInnerPolys",
    TestCubeAxesWithXInnerPolys
  },
  {
    "TestCubeAxesWithXLines",
    TestCubeAxesWithXLines
  },
  {
    "TestCubeAxesWithYInnerGrids",
    TestCubeAxesWithYInnerGrids
  },
  {
    "TestCubeAxesWithYInnerPolys",
    TestCubeAxesWithYInnerPolys
  },
  {
    "TestCubeAxesWithYLines",
    TestCubeAxesWithYLines
  },
  {
    "TestCubeAxesWithZInnerGrids",
    TestCubeAxesWithZInnerGrids
  },
  {
    "TestCubeAxesWithZInnerPolys",
    TestCubeAxesWithZInnerPolys
  },
  {
    "TestCubeAxesWithZLines",
    TestCubeAxesWithZLines
  },
  {
    "TestEmptyCornerAnnotation",
    TestEmptyCornerAnnotation
  },
  {
    "TestLegendBoxActor",
    TestLegendBoxActor
  },
  {
    "TestLegendBoxActor2",
    TestLegendBoxActor2
  },
  {
    "TestLegendScaleActor",
    TestLegendScaleActor
  },
  {
    "TestPieChartActor",
    TestPieChartActor
  },
  {
    "TestPolarAxes",
    TestPolarAxes
  },
  {
    "TestScalarBar",
    TestScalarBar
  },
  {
    "TestScalarBarAboveBelow",
    TestScalarBarAboveBelow
  },
  {
    "TestSpiderPlotActor",
    TestSpiderPlotActor
  },
  {
    "TestXYPlotActor",
    TestXYPlotActor
  },

  { NULL, NULL } /* NOLINT */
};

static const int NumTests =
  (sizeof(cmakeGeneratedFunctionMapEntries) / sizeof(functionMapEntry)) - 1;

/* Allocate and create a lowercased copy of string
   (note that it has to be free'd manually) */
static char* lowercase(const char* string)
{
  char *new_string, *p;
  size_t stringSize = 0;

  stringSize = CM_CAST(size_t, strlen(string) + 1);
  new_string = CM_CAST(char*, malloc(sizeof(char) * stringSize));

  if (new_string == NULL) { /* NOLINT */
    return NULL;            /* NOLINT */
  }
  strncpy(new_string, string, stringSize);
  for (p = new_string; *p != 0; ++p) {
    *p = CM_CAST(char, tolower(*p));
  }
  return new_string;
}

int main(int ac, char* av[])
{
  int i, testNum = 0, partial_match;
  char *arg, *test_name;
  int testToRun = -1;

  

  /* If no test name was given */
  /* process command line with user function.  */
  if (ac < 2) {
    /* Ask for a test.  */
    printf("Available tests:\n");
    for (i = 0; i < NumTests; ++i) {
      printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
    }
    printf("To run a test, enter the test number: ");
    fflush(stdout);
    if (scanf("%d", &testNum) != 1) {
      printf("Couldn't parse that input as a number\n");
      return -1;
    }
    if (testNum >= NumTests) {
      printf("%3d is an invalid test number.\n", testNum);
      return -1;
    }
    testToRun = testNum;
    ac--;
    av++;
  }
  partial_match = 0;
  arg = NULL; /* NOLINT */
  /* If partial match is requested.  */
  if (testToRun == -1 && ac > 1) {
    partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0;
  }
  if (partial_match != 0 && ac < 3) {
    printf("-R needs an additional parameter.\n");
    return -1;
  }
  if (testToRun == -1) {
    arg = lowercase(av[1 + partial_match]);
  }
  for (i = 0; i < NumTests && testToRun == -1; ++i) {
    test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name);
    if (partial_match != 0 && strstr(test_name, arg) != NULL) { /* NOLINT */
      testToRun = i;
      ac -= 2;
      av += 2;
    } else if (partial_match == 0 && strcmp(test_name, arg) == 0) {
      testToRun = i;
      ac--;
      av++;
    }
    free(test_name);
  }
  free(arg);
  if (testToRun != -1) {
    int result;
    vtksys::SystemInformation::SetStackTraceOnError(1);
 
    // Set defaults
    vtkTestingInteractor::ValidBaseline = "Use_-V_for_Baseline";
    vtkTestingInteractor::TempDirectory =
      std::string("E:/CODE/VTK/BUILD/Testing/Temporary");
    vtkTestingInteractor::DataDirectory = std::string("Use_-D_for_Data");

    int interactive = 0;
    for (int ii = 0; ii < ac; ++ii)
      {
      if (strcmp(av[ii], "-I") == 0)
        {
        interactive = 1;
        continue;
        }
      if (strcmp(av[ii], "-V") == 0 && ii < ac-1)
        {
        vtkTestingInteractor::ValidBaseline = std::string(av[++ii]);
        continue;
        }
      if (strcmp(av[ii], "-T") == 0 && ii < ac-1)
        {
        vtkTestingInteractor::TempDirectory = std::string(av[++ii]);
        continue;
        }
      if (strcmp(av[ii], "-D") == 0 && ii < ac-1)
        {
        vtkTestingInteractor::DataDirectory = std::string(av[++ii]);
        continue;
        }
      if (strcmp(av[ii], "-E") == 0 && ii < ac-1)
        {
        vtkTestingInteractor::ErrorThreshold =
            static_cast<double>(atof(av[++ii]));
        continue;
        }
      }
    vtkSmartPointer<vtkTestingObjectFactory> factory = vtkSmartPointer<vtkTestingObjectFactory>::New();
    if (!interactive)
      {
      // Disable any other overrides before registering our factory.
      vtkObjectFactoryCollection *collection = vtkObjectFactory::GetRegisteredFactories();
      collection->InitTraversal();
      vtkObjectFactory *f = collection->GetNextItem();
      while (f)
        {
        f->Disable("vtkRenderWindowInteractor");
        f = collection->GetNextItem();
        }
      vtkObjectFactory::RegisterFactory(factory);
      }

    if (testToRun < 0 || testToRun >= NumTests) {
      printf("testToRun was modified by TestDriver code to an invalid value: "
             "%3d.\n",
             testNum);
      return -1;
    }
    result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av);

   if (!interactive)
     {
     if (vtkTestingInteractor::TestReturnStatus != -1)
        {
        if (vtkTestingInteractor::TestReturnStatus != vtkTesting::PASSED)
          {
          result = EXIT_FAILURE;
          }
        else
          {
          result = EXIT_SUCCESS;
          }
        }
      vtkObjectFactory::UnRegisterFactory(factory);
      }

    return result;
  }

  /* Nothing was run, display the test names.  */
  printf("Available tests:\n");
  for (i = 0; i < NumTests; ++i) {
    printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
  }
  printf("Failed: %s is an invalid test name.\n", av[1]);

  return -1;
}
